<template>
	<div>
		<el-cascader ref="cascadRef" class="oper-cascader" v-model="cascaValue" :placeholder="configure.placeholder"
			:filterable="configure.filterable" :props="props.configure.lazy" :options="props.configure.options"
			:disabled="props.configure.disabled"
			:clearable="props.configure.clearable == undefined ? true : props.configure.clearable"
			@expand-change="expandChange" @change="onChange" />
	</div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from "vue";
import { CascaderType } from "./type";
import { CascaderValue, ElCascader } from "element-plus";
import { createBtns } from "./generate-btns";

const props = withDefaults(
	defineProps<{
		modelValue: string[] | number[];
		configure: CascaderType;
		isPreview?: boolean;
	}>(),
	{
		configure: () => ({
			lazy: {},
			autoClose: true,
			valueKeys: "value",
			options: [] as any,
			isPreview: false,
		}),
	}
);

const emits = defineEmits<{
	"update:modelValue": [string[] | number[]];
	"onChange": [string[] | number[]];
}>();

const cascadRef = ref<InstanceType<typeof ElCascader> | null>(null);
// 非点击确认按钮时给出的参数
const cascaValue = ref(props.modelValue);
// 当用户点击确认按钮时给出的参数
const expandValue = ref<number[] | string[]>([]);

const onChange = () => {
	props.configure.change && props.configure.change(cascaValue.value, getResult());
	emits("onChange", cascaValue.value);
	emits("update:modelValue", cascaValue.value);
};

const expandChange = (value: CascaderValue) => {
	expandValue.value = value as number[] | string[];
};

const getResult = () => {
	const key = props.configure.valueKeys || "value";
	const nodes = cascadRef.value?.getCheckedNodes(false)?.at(0);
	if (key === "label") {
		return nodes?.pathLabels || [];
	} else if (key === "value") {
		return cascaValue.value;
	} else {
		return {
			label: nodes?.pathLabels || [],
			value: cascaValue.value,
		};
	}
};

const getExpandResult = () => {
	const key = props.configure.valueKeys || "object";
	if (key === "value") return expandValue.value;
	const menus = cascadRef.value?.cascaderPanelRef?.menus || [];
	const array = menus.reduce((prev, m) => {
		prev.push(...m);
		return prev;
	}, []);
	const result: { label: string; value: string }[] = [];
	array
		// @ts-ignore
		.filter((node: any) => expandValue.value.includes(node.value))
		.forEach(n => {
			result.push({
				label: n.label,
				value: n.value as string,
			});
		});

	if (key === "label") return result.map(r => r.label);
	return result;
};

const generateBtns = () => {
	const { appendButton } = props.configure;
	if (appendButton) {
		const { cancel } = appendButton;
		const close = () => cascadRef.value?.togglePopperVisible(false);
		const _confirm = () => {
			cascaValue.value = expandValue.value;
			const result = getExpandResult();
			props.configure.change && props.configure.change(cascaValue.value, result);
			// confirm && confirm(expandValue.value, result, close);
			close();
		};

		const _cancel = () => {
			cancel && cancel();
			close();
		};

		createBtns(_confirm, _cancel);
	}
};

watch(
	() => props.modelValue,
	v => {
		cascaValue.value = v;
	},
	{ immediate: true, deep: true }
);

onMounted(() => {
	if (props.configure.appendButton) generateBtns();
});
</script>


